package metrics;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Random;

import summarizer.newversion.RandomSummarizer;
import summarizer.newversion.Summarizer;
import thesis.InfoUnit;
import thesis.DataObject;
import thesis.Summary;

import com.aliasi.util.Arrays;
import com.aliasi.util.Pair;

public class Evaluate {
	public static double corrRougeJS(int M, int numberOfPages,
			HashMap<Long, DataObject> tweetsCopy, int dimSize,
			ArrayList<InfoUnit> units, double[][] probs) {
		toBinary(tweetsCopy.values(), units, probs);
		Summarizer summarizer = new RandomSummarizer();
		final int repeat = 300;
		double[] rouge = new double[repeat];
		double[] js = new double[repeat];
		for (int i = 0; i < repeat; i++) {
			int K = new Random().nextInt(50);
			Summary summary = summarizer.computeSummary(M + K, numberOfPages,
					(HashMap<Long, DataObject>) tweetsCopy.clone(), dimSize);
			rouge[i] = Rouge.getScore(summary, tweetsCopy.values(), units,
					probs);
			js[i] = JSDivergence.getScore(summary, tweetsCopy.values(), units,
					probs);
			System.out.println(rouge[i] + "\t" + js[i]);
		}
		double totalR = 0, totalJ = 0;
		for (int i = 0; i < repeat; i++) {
			totalR += rouge[i];
			totalJ += js[i];
		}
		double aveR = totalR / repeat, aveJ = totalJ / repeat;
		double mix = 0, R2 = 0, J2 = 0;
		for (int i = 0; i < repeat; i++) {
			mix += (rouge[i] - aveR) * (js[i] - aveJ);
			R2 += (rouge[i] - aveR) * (rouge[i] - aveR);
			J2 += (js[i] - aveJ) * (js[i] - aveJ);
		}
		return mix / Math.sqrt(R2 * J2);
	}

	public static void toBinary(final Collection<DataObject> allData,
			final ArrayList<InfoUnit> units, double[][] probs) {
//		for (DataObject t : allData) {
//			ArrayList<Pair<Double, ArrayList<Double>>> rels = t.getRels();
//			for (Pair<Double, ArrayList<Double>> pair : rels) {
//				for (int i = 0; i < pair.b().size(); i++) {
//					double rd = new Random().nextDouble();
//					pair.b().set(i, (rd < pair.b().get(i)) ? 1.0 : 0.0);
//				}
//			}
//		}
//		for (InfoUnit unit : units) {
//			ArrayList<Pair<Integer, Integer>> dimVals = unit.getDimValues();
//			for (DataObject t : allData) {
//				boolean hit = true;
//				for (Pair<Integer, Integer> pair : dimVals) {
//					if (t.getRel(pair.a(), pair.b()) != 1) {
//						hit = false;
//						break;
//					}
//				}
//				probs[t.getInternId()][unit.getInternId()] = hit ? 1 : 0;
//			}
//
//		}
		for (int i = 0; i < probs.length; i++) {
			for (int j = 0; j < probs[i].length; j++) {
				double rd = new Random().nextDouble();
				probs[i][j] = rd < probs[i][j] ? 1 : 0;
			}
		}
	}

	public static void evaluate(int M, ArrayList<Summary[]> multiSummary,
			ArrayList<Summarizer> summarizers,
			final Collection<DataObject> allData, ArrayList<InfoUnit> units,
			double[][] probs) {
		double[][] ground = new double[probs.length][probs[0].length];
		for (int i = 0; i < probs.length; i++) {
			for (int j = 0; j < probs[0].length; j++) {
				ground[i][j] = probs[i][j];
			}
		}
		toBinary(allData, units, ground);
		// ROUGE
		System.out.println();
		System.out.printf("%d\t", M);
		for (int i = 0; i < multiSummary.size(); i++) {
			double aveScore = 0;
			for (Summary summary : multiSummary.get(i)) {
				double score = Rouge.getScore(summary, allData, units, ground);
				aveScore += score;
			}
			aveScore /= multiSummary.get(i).length;
			System.out.printf("%.3f\t", aveScore);
		}
		System.out.print("\t\t");
		for (int i = 0; i < multiSummary.size(); i++) {
			double aveScore = 0;
			for (Summary summary : multiSummary.get(i)) {
				double score = JSDivergence.getScore(summary, allData, units,
						ground);
				aveScore += score;
			}
			aveScore /= multiSummary.get(i).length;
			System.out.printf("%.4f\t", aveScore);
		}

		System.out.print("\t\t");
		for (int i = 0; i < multiSummary.size(); i++) {
			double aveScore = 0;
			for (Summary summary : multiSummary.get(i)) {
				double score = Quality
						.getScore(summary, allData, units, ground);
				aveScore += score;
			}
			aveScore /= multiSummary.get(i).length;
			System.out.printf("%.4f\t", aveScore);
		}
	}
}
